<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,IE=9,chrome=1"><meta name="generator" content="MATLAB 2021b"><title>Call and Provide ROS Services</title><style type="text/css">.rtcContent { padding: 30px; } .S0 { margin: 3px 10px 5px 4px; padding: 0px; line-height: 28.8px; min-height: 0px; white-space: pre-wrap; color: rgb(213, 80, 0); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 24px; font-weight: 400; text-align: left;  }
.S1 { margin: 2px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(0, 0, 0); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left;  }
.S2 { margin: 10px 0px 20px; padding-left: 0px; font-family: Helvetica, Arial, sans-serif; font-size: 14px;  }
.S3 { margin-left: 56px; line-height: 21px; min-height: 0px; text-align: left; white-space: pre-wrap;  }
.S4 { margin: 20px 10px 5px 4px; padding: 0px; line-height: 20px; min-height: 0px; white-space: pre-wrap; color: rgb(60, 60, 60); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 20px; font-weight: 700; text-align: left;  }
.CodeBlock { background-color: #F7F7F7; margin: 10px 0 10px 0;}
.S5 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 0px none rgb(0, 0, 0); border-radius: 4px 4px 0px 0px; padding: 6px 45px 0px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S6 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 0px none rgb(0, 0, 0); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 0px; padding: 0px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S7 { color: rgb(64, 64, 64); padding: 10px 0px 6px 17px; background: rgb(255, 255, 255) none repeat scroll 0% 0% / auto padding-box border-box; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; overflow-x: hidden; line-height: 17.234px;  }
/* Styling that is common to warnings and errors is in diagnosticOutput.css */.embeddedOutputsErrorElement {    min-height: 18px;    max-height: 550px;}
.embeddedOutputsErrorElement .diagnosticMessage-errorType {    overflow: auto;}
.embeddedOutputsErrorElement.inlineElement {}
.embeddedOutputsErrorElement.rightPaneElement {}
/* Styling that is common to warnings and errors is in diagnosticOutput.css */.embeddedOutputsWarningElement {    min-height: 18px;    max-height: 550px;}
.embeddedOutputsWarningElement .diagnosticMessage-warningType {    overflow: auto;}
.embeddedOutputsWarningElement.inlineElement {}
.embeddedOutputsWarningElement.rightPaneElement {}
/* Copyright 2015-2019 The MathWorks, Inc. *//* In this file, styles are not scoped to rtcContainer since they could be in the Dojo Tooltip */.diagnosticMessage-wrapper {    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;    font-size: 12px;}
.diagnosticMessage-wrapper.diagnosticMessage-warningType {    color: rgb(255,100,0);}
.diagnosticMessage-wrapper.diagnosticMessage-warningType a {    color: rgb(255,100,0);    text-decoration: underline;}
.diagnosticMessage-wrapper.diagnosticMessage-errorType {    color: rgb(230,0,0);}
.diagnosticMessage-wrapper.diagnosticMessage-errorType a {    color: rgb(230,0,0);    text-decoration: underline;}
.diagnosticMessage-wrapper .diagnosticMessage-messagePart,.diagnosticMessage-wrapper .diagnosticMessage-causePart {    white-space: pre-wrap;}
.diagnosticMessage-wrapper .diagnosticMessage-stackPart {    white-space: pre;}
.embeddedOutputsTextElement,.embeddedOutputsVariableStringElement {    white-space: pre;    word-wrap:  initial;    min-height: 18px;    max-height: 550px;}
.embeddedOutputsTextElement .textElement,.embeddedOutputsVariableStringElement .textElement {    overflow: auto;}
.textElement,.rtcDataTipElement .textElement {    padding-top: 3px;}
.embeddedOutputsTextElement.inlineElement,.embeddedOutputsVariableStringElement.inlineElement {}
.inlineElement .textElement {}
.embeddedOutputsTextElement.rightPaneElement,.embeddedOutputsVariableStringElement.rightPaneElement {    min-height: 16px;}
.rightPaneElement .textElement {    padding-top: 2px;    padding-left: 9px;}
.S8 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 0px 0px 4px 4px; padding: 6px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S9 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 4px 4px 0px 0px; padding: 6px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S10 { margin: 3px 10px 5px 4px; padding: 0px; line-height: 20px; min-height: 0px; white-space: pre-wrap; color: rgb(60, 60, 60); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 20px; font-weight: 700; text-align: left;  }
.S11 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 1px solid rgb(233, 233, 233); border-radius: 4px; padding: 6px 45px 4px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S12 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 1px solid rgb(233, 233, 233); border-bottom: 0px none rgb(0, 0, 0); border-radius: 0px; padding: 6px 45px 0px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S13 { border-left: 1px solid rgb(233, 233, 233); border-right: 1px solid rgb(233, 233, 233); border-top: 0px none rgb(0, 0, 0); border-bottom: 0px none rgb(0, 0, 0); border-radius: 0px; padding: 0px 45px 0px 13px; line-height: 17.234px; min-height: 18px; white-space: nowrap; color: rgb(0, 0, 0); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px;  }
.S14 { margin: 10px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(0, 0, 0); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left;  }</style></head><body><div class = rtcContent><h1  class = 'S0'><span>Call and Provide ROS Services</span></h1><div  class = 'S1'><span>ROS支持两种主要的通信机制：话题和服务。话题具有发布者和订阅者，用于发送和接收消息（请参阅 </span><a href = "docid:ros_ug.mw_fa34dc6f-351e-4ab5-8680-46563496814b"><span>Exchange Data with ROS Publishers and Subscribers</span></a><span>）。另一方面，</span><span style=' font-weight: bold;'>服务</span><span>通过允许请求-响应通信来实现更紧密的耦合。</span><span style=' font-weight: bold;'>服务客户端</span><span>向服务服务器发送请求消息并等待响应。服务器将使用请求中的数据来构造响应消息并将其发送回客户端。每个服务都有一个确定请求和响应消息结构的类型。服务还有一个在ROS网络中唯一的名称。</span></div><div  class = 'S1'><span>该服务通信具有以下特点：</span></div><ul  class = 'S2'><li  class = 'S3'><span>服务请求（或服务呼叫）用于一对一通信。单个节点将启动请求，只有一个节点将接收请求并发送回响应。</span></li><li  class = 'S3'><span>当执行服务调用时，客户端和服务器紧密耦合。服务器需要在服务调用时存在，一旦发送请求，客户端将阻塞，直到收到响应。</span></li></ul><div  class = 'S1'><span>服务的概念如下图所示：</span></div><div  class = 'S1'><img class = "imageNode" src = "" width = "789" height = "455" alt = "" style = "vertical-align: baseline; width: 789px; height: 455px;"></img></div><div  class = 'S1'><span>这个例子向您展示了如何设置服务服务器来向ROS网络发布服务。此外，您将学习如何使用服务客户端调用服务器并接收响应。</span></div><div  class = 'S1'><span>Prerequisites:</span><span> </span><a href = "docid:ros_ug.mw_cb3fdf75-613d-45b1-90e1-aad102b9a24a"><span>Get Started with ROS</span></a><span>, </span><span> </span><a href = "docid:ros_ug.mw_d625a603-7f37-4925-9470-2de734937434"><span>Connect to a ROS Network</span></a><span>, </span><span> </span><a href = "docid:ros_ug.mw_fa34dc6f-351e-4ab5-8680-46563496814b"><span>Exchange Data with ROS Publishers and Subscribers</span></a></div><h2  class = 'S4'><span>Create Service Server</span></h2><div  class = 'S1'><span>在检查服务概念之前，启动MATLAB®中的ROS主程序和样本ROS网络。</span><span style=' font-family: monospace;'>exampleHelperROSCreateSampleNetwork</span><span>将创建一些服务服务器来模拟真实的ROS网络。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S5'><span style="white-space: pre"><span >clear,clc,close </span><span style="color: rgb(170, 4, 249);">all</span><span >;</span></span></div></div><div class="inlineWrapper outputs"><div  class = 'S6'><span style="white-space: pre"><span >rosinit</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="35A3214F" data-testid="output_0" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="61" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">Launching ROS Core...
...........Done in 4.517 seconds.
Initializing ROS master on http://192.168.118.1:11311.
Initializing global node /matlab_global_node_23384 with NodeURI http://LAPTOP-TG3AQJDL:1096/</div></div></div></div><div class="inlineWrapper"><div  class = 'S8'><span style="white-space: pre"><span >exampleHelperROSCreateSampleNetwork</span></span></div></div></div><div  class = 'S1'><span>假设您想创建一个简单的服务服务器，在您调用服务时显示“服务客户端正在调用</span><span style=' font-style: italic;'>A service client is calling</span><span>”。使用</span><a href = "docid:ros_ref.bupf5_j_11"><span style=' font-family: monospace;'>rossvcserver</span></a><span> 命令创建服务。指定服务名称和服务消息类型。还将回调函数定义为</span><span style=' font-family: monospace;'>exampleHelperROSEmptyCallback</span><span>。服务服务器的回调函数具有非常特定的签名。有关详细信息，请参阅</span><a href = "docid:ros_ref.bupf5_j_11"><span style=' font-family: monospace;'>rossvcserver</span></a><span>的文档。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >testserver = rossvcserver(</span><span style="color: rgb(170, 4, 249);">'/test'</span><span >, </span><span style="color: rgb(170, 4, 249);">'std_srvs/Empty'</span><span >, @exampleHelperROSEmptyCallback)</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="FA4E7DE8" data-testid="output_1" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="93" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">testserver = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ServiceServer - 属性:

      ServiceType: 'std_srvs/Empty'
      ServiceName: '/test'
    NewRequestFcn: @exampleHelperROSEmptyCallback
</div></div></div></div></div></div><div  class = 'S1'><span>当您列出ROS网络中的所有服务时，可以看到您的新服务</span><span style=' font-family: monospace;'>/test</span><span>。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >rosservice </span><span style="color: rgb(170, 4, 249);">list</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="9D3C7DFE" data-testid="output_2" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="162" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">/add
/matlab_global_node_23384/get_loggers
/matlab_global_node_23384/set_logger_level
/node_1/get_loggers
/node_1/set_logger_level
/node_2/get_loggers
/node_2/set_logger_level
/node_3/get_loggers
/node_3/set_logger_level
/reply
/test</div></div></div></div></div><div  class = 'S1'><span>您可以使用</span><a href = "docid:ros_ref.bupf5_j_7"><span style=' font-family: monospace;'>rosservice</span></a><span style=' font-family: monospace;'> info</span><span>.获得有关您的服务的更多信息。全局节点列为可访问服务服务器的节点，您还可以看到它的</span><span style=' font-family: monospace;'>std_srvs/Empty</span><span> 服务类型。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >rosservice </span><span style="color: rgb(170, 4, 249);">info /test</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="AD395C65" data-testid="output_3" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="61" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">Node: /matlab_global_node_23384
URI: rosrpc://LAPTOP-TG3AQJDL:1095
Type: std_srvs/Empty
Args:</div></div></div></div></div><h2  class = 'S10'><span>Create Service Client</span></h2><div  class = 'S1'><span>使用服务客户端从ROS服务服务器请求信息。要创建客户端，请使用服务名为参数的</span><a href = "docid:ros_ref.bupf5_j_10"><span style=' font-family: monospace;'>rossvcclient</span></a><span> 。为我们刚刚创建的 </span><span style=' font-family: monospace;'>/test</span><span> 服务创建一个服务客户机。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >testclient = rossvcclient(</span><span style="color: rgb(170, 4, 249);">'/test'</span><span >)</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="9B835F0A" data-testid="output_4" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="78" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">testclient = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ServiceClient - 属性:

    ServiceType: 'std_srvs/Empty'
    ServiceName: '/test'
</div></div></div></div></div></div><div  class = 'S1'><span>为服务创建空请求消息。使用 </span><a href = "docid:ros_ref.bupf5_j_2"><span style=' font-family: monospace;'>rosmessage</span></a><span> 函数并将客户端作为第一个参数传递。这将创建具有服务指定的消息类型的服务请求函数</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >testreq = rosmessage(testclient)</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="1DC20D01" data-testid="output_5" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="93" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">testreq = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ROS EmptyRequest message with properties:

    MessageType: 'std_srvs/EmptyRequest'

  Use showdetails to show the contents of the message
</div></div></div></div></div></div><div  class = 'S1'><span>要从服务器获取响应时，请使用</span><a href = "docid:ros_ref.buqbgqj"><span style=' font-family: monospace;'>call</span></a><span>函数，该函数调用服务服务器并返回响应。之前创建的服务服务器将返回空响应。此外，它将调用</span><span style=' font-family: monospace;'>exampleHelperROSEmptyCallback</span><span>函数并显示字符串“</span><span style=' font-style: italic;'>A service client is calling</span><span>”。您还可以定义一个</span><span style=' font-family: monospace;'>Timeout</span><span>参数，该参数指示客户机应等待响应多长时间。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S11'><span style="white-space: pre"><span >testresp = call(testclient,testreq,</span><span style="color: rgb(170, 4, 249);">'Timeout'</span><span >,3);</span></span></div></div></div><h2  class = 'S10'><span>Create a Service for Adding Two Numbers</span></h2><div  class = 'S1'><span>到目前为止，服务服务器还没有做任何有意义的工作，但是您可以使用服务进行计算和数据操作。创建添加两个整数的服务。</span></div><div  class = 'S1'><span>我们可以使用现有的服务类型</span><span style=' font-family: monospace;'>roscpp_tutorials/TwoInts</span><span>执行此任务。您可以通过调用</span><span style=' font-family: monospace;'>rosmsg show</span><span>来检查请求和响应消息的结构。请求包含两个整数A和B，响应包含它们的加法和。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >rosmsg </span><span style="color: rgb(170, 4, 249);">show roscpp_tutorials/TwoIntsRequest</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="CBD44A5F" data-testid="output_6" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="32" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">int64 A
int64 B</div></div></div></div><div class="inlineWrapper"><div  class = 'S12'></div></div><div class="inlineWrapper outputs"><div  class = 'S6'><span style="white-space: pre"><span >rosmsg </span><span style="color: rgb(170, 4, 249);">show roscpp_tutorials/TwoIntsResponse</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="D717F664" data-testid="output_7" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="18" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">int64 Sum</div></div></div></div></div><div  class = 'S1'><span>使用此消息类型和计算添加的回调函数创建服务服务器。为了方便起见，</span><span style=' font-family: monospace;'>exampleHelperROSSumCallback</span><span>函数已经实现了此计算。将函数指定为回调函数。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >sumserver = rossvcserver(</span><span style="color: rgb(170, 4, 249);">'/sum'</span><span >, </span><span style="color: rgb(170, 4, 249);">'roscpp_tutorials/TwoInts'</span><span >, @exampleHelperROSSumCallback)</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="B910AFDF" data-testid="output_8" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="93" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">sumserver = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ServiceServer - 属性:

      ServiceType: 'roscpp_tutorials/TwoInts'
      ServiceName: '/sum'
    NewRequestFcn: @exampleHelperROSSumCallback
</div></div></div></div></div></div><div  class = 'S1'><span>要调用服务服务器，必须创建服务客户端。注意，这个客户端可以在ROS网络的任何地方创建。在本例中，我们将在MATLAB中为 </span><span style=' font-family: monospace;'>/sum</span><span> 服务创建一个客户机。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >sumclient = rossvcclient(</span><span style="color: rgb(170, 4, 249);">'/sum'</span><span >)</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="5F12C9CA" data-testid="output_9" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="78" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">sumclient = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ServiceClient - 属性:

    ServiceType: 'roscpp_tutorials/TwoInts'
    ServiceName: '/sum'
</div></div></div></div></div></div><div  class = 'S1'><span>创建请求消息。您可以定义两个整数A和B，这两个整数在使用 </span><a href = "docid:ros_ref.buqbgqj"><span style=' font-family: monospace;'>call</span></a><span> 命令时相加。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S5'><span style="white-space: pre"><span >sumreq = rosmessage(sumclient);</span></span></div></div><div class="inlineWrapper"><div  class = 'S13'><span style="white-space: pre"><span >sumreq.A = 2;</span></span></div></div><div class="inlineWrapper outputs"><div  class = 'S6'><span style="white-space: pre"><span >sumreq.B = 1</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="817A529A" data-testid="output_10" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="122" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">sumreq = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ROS TwoIntsRequest message with properties:

    MessageType: 'roscpp_tutorials/TwoIntsRequest'
              A: 2
              B: 1

  Use showdetails to show the contents of the message
</div></div></div></div></div></div><div  class = 'S1'><span>预期这两个数字的和是3。要调用服务，请使用以下命令。服务响应消息将包含Sum属性，该属性存储A和B的加法。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >sumresp = call(sumclient,sumreq,</span><span style="color: rgb(170, 4, 249);">'Timeout'</span><span >,3)</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsVariableStringElement" uid="C44B9F19" data-testid="output_11" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="107" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><span class="variableNameElement" style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">sumresp = </span></div><div style="white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">  ROS TwoIntsResponse message with properties:

    MessageType: 'roscpp_tutorials/TwoIntsResponse'
            Sum: 3

  Use showdetails to show the contents of the message
</div></div></div></div></div></div><h2  class = 'S10'><span>Shut Down ROS Network</span></h2><div  class = 'S1'><span>从ROS网络中删除示例节点和服务服务器。</span></div><div class="CodeBlock"><div class="inlineWrapper"><div  class = 'S11'><span style="white-space: pre"><span >exampleHelperROSShutDownSampleNetwork</span></span></div></div></div><div  class = 'S14'><span>关闭ROS主机并删除全局节点。</span></div><div class="CodeBlock"><div class="inlineWrapper outputs"><div  class = 'S9'><span style="white-space: pre"><span >rosshutdown</span></span></div><div  class = 'S7'><div class="inlineElement eoOutputWrapper embeddedOutputsTextElement" uid="ADEF3ECD" data-testid="output_12" style="width: 716px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;"><div class="textElement eoOutputContent" data-width="686" data-height="32" data-hashorizontaloverflow="false" style="max-height: 261px; white-space: pre; font-style: normal; color: rgb(64, 64, 64); font-size: 12px;">Shutting down global node /matlab_global_node_23384 with NodeURI http://LAPTOP-TG3AQJDL:1096/
Shutting down ROS master on http://192.168.118.1:11311.</div></div></div></div><div class="inlineWrapper"><div  class = 'S8'><span style="white-space: pre"><span >clear</span></span></div></div></div><h2  class = 'S10'><span>Next Steps</span></h2><ul  class = 'S2'><li  class = 'S3'><span>Refer to</span><span> </span><a href = "docid:ros_ug.mw_2b4c1056-431d-4413-a812-7cd07f4d9a36"><span>Work with Basic ROS Messages</span></a><span> to explore how ROS messages are represented in MATLAB.</span></li></ul><div  class = 'S1'><span style=' font-style: italic;'>Copyright 2014-2016 The MathWorks, Inc.</span></div><div  class = 'S1'></div>
<br>
<!-- 
##### SOURCE BEGIN #####
%% Call and Provide ROS Services
% ROS支持两种主要的通信机制：话题和服务。话题具有发布者和订阅者，用于发送和接收消息（请参阅 <docid:ros_ug.mw_fa34dc6f-351e-4ab5-8680-46563496814b 
% Exchange Data with ROS Publishers and Subscribers>）。另一方面，*服务*通过允许请求-响应通信来实现更紧密的耦合。*服务客户端*向服务服务器发送请求消息并等待响应。服务器将使用请求中的数据来构造响应消息并将其发送回客户端。每个服务都有一个确定请求和响应消息结构的类型。服务还有一个在ROS网络中唯一的名称。
% 
% 该服务通信具有以下特点：
%% 
% * 服务请求（或服务呼叫）用于一对一通信。单个节点将启动请求，只有一个节点将接收请求并发送回响应。
% * 当执行服务调用时，客户端和服务器紧密耦合。服务器需要在服务调用时存在，一旦发送请求，客户端将阻塞，直到收到响应。
%% 
% 服务的概念如下图所示：
% 
% 
% 
% 这个例子向您展示了如何设置服务服务器来向ROS网络发布服务。此外，您将学习如何使用服务客户端调用服务器并接收响应。
% 
% Prerequisites: <docid:ros_ug.mw_cb3fdf75-613d-45b1-90e1-aad102b9a24a Get Started 
% with ROS>,  <docid:ros_ug.mw_d625a603-7f37-4925-9470-2de734937434 Connect to 
% a ROS Network>,  <docid:ros_ug.mw_fa34dc6f-351e-4ab5-8680-46563496814b Exchange 
% Data with ROS Publishers and Subscribers>
%% Create Service Server
% 在检查服务概念之前，启动MATLAB®中的ROS主程序和样本ROS网络。|exampleHelperROSCreateSampleNetwork|将创建一些服务服务器来模拟真实的ROS网络。

clear,clc,close all;
rosinit
exampleHelperROSCreateSampleNetwork
%% 
% 假设您想创建一个简单的服务服务器，在您调用服务时显示“服务客户端正在调用_A service client is calling_”。使用<docid:ros_ref.bupf5_j_11 
% |rossvcserver|> 命令创建服务。指定服务名称和服务消息类型。还将回调函数定义为|exampleHelperROSEmptyCallback|。服务服务器的回调函数具有非常特定的签名。有关详细信息，请参阅<docid:ros_ref.bupf5_j_11 
% |rossvcserver|>的文档。

testserver = rossvcserver('/test', 'std_srvs/Empty', @exampleHelperROSEmptyCallback)
%% 
% 当您列出ROS网络中的所有服务时，可以看到您的新服务|/test|。

rosservice list
%% 
% 您可以使用<docid:ros_ref.bupf5_j_7 |rosservice|> |info|.获得有关您的服务的更多信息。全局节点列为可访问服务服务器的节点，您还可以看到它的|std_srvs/Empty| 
% 服务类型。

rosservice info /test
%% Create Service Client
% 使用服务客户端从ROS服务服务器请求信息。要创建客户端，请使用服务名为参数的<docid:ros_ref.bupf5_j_10 |rossvcclient|> 
% 。为我们刚刚创建的 |/test| 服务创建一个服务客户机。

testclient = rossvcclient('/test')
%% 
% 为服务创建空请求消息。使用 <docid:ros_ref.bupf5_j_2 |rosmessage|> 函数并将客户端作为第一个参数传递。这将创建具有服务指定的消息类型的服务请求函数

testreq = rosmessage(testclient)
%% 
% 要从服务器获取响应时，请使用<docid:ros_ref.buqbgqj |call|>函数，该函数调用服务服务器并返回响应。之前创建的服务服务器将返回空响应。此外，它将调用|exampleHelperROSEmptyCallback|函数并显示字符串“_A 
% service client is calling_”。您还可以定义一个|Timeout|参数，该参数指示客户机应等待响应多长时间。

testresp = call(testclient,testreq,'Timeout',3);
%% Create a Service for Adding Two Numbers
% 到目前为止，服务服务器还没有做任何有意义的工作，但是您可以使用服务进行计算和数据操作。创建添加两个整数的服务。
% 
% 我们可以使用现有的服务类型|roscpp_tutorials/TwoInts|执行此任务。您可以通过调用|rosmsg show|来检查请求和响应消息的结构。请求包含两个整数A和B，响应包含它们的加法和。

rosmsg show roscpp_tutorials/TwoIntsRequest

rosmsg show roscpp_tutorials/TwoIntsResponse
%% 
% 使用此消息类型和计算添加的回调函数创建服务服务器。为了方便起见，|exampleHelperROSSumCallback|函数已经实现了此计算。将函数指定为回调函数。

sumserver = rossvcserver('/sum', 'roscpp_tutorials/TwoInts', @exampleHelperROSSumCallback)
%% 
% 要调用服务服务器，必须创建服务客户端。注意，这个客户端可以在ROS网络的任何地方创建。在本例中，我们将在MATLAB中为 |/sum| 服务创建一个客户机。

sumclient = rossvcclient('/sum')
%% 
% 创建请求消息。您可以定义两个整数A和B，这两个整数在使用 <docid:ros_ref.buqbgqj |call|> 命令时相加。

sumreq = rosmessage(sumclient);
sumreq.A = 2;
sumreq.B = 1
%% 
% 预期这两个数字的和是3。要调用服务，请使用以下命令。服务响应消息将包含Sum属性，该属性存储A和B的加法。

sumresp = call(sumclient,sumreq,'Timeout',3)
%% Shut Down ROS Network
% 从ROS网络中删除示例节点和服务服务器。

exampleHelperROSShutDownSampleNetwork
%% 
% 关闭ROS主机并删除全局节点。

rosshutdown
clear
%% Next Steps
%% 
% * Refer to <docid:ros_ug.mw_2b4c1056-431d-4413-a812-7cd07f4d9a36 Work with 
% Basic ROS Messages> to explore how ROS messages are represented in MATLAB.
%% 
% _Copyright 2014-2016 The MathWorks, Inc._
% 
%
##### SOURCE END #####
-->
</div></body></html>